<template>
  <div>
    <canvas
      ref="canvas"
      @mousedown="mouseDown"
      @mousemove="mouseMove"
      @mouseup="mouseUp"
      @touchstart="touchStart"
      @touchmove="touchMove"
      @touchend="touchEnd"
    ></canvas>

    <canvas ref="readcanvas"> </canvas>
  </div>
</template>

<script>
export default {
  name: "signatureField",
  props: {
    // 签字栏宽
    // width: {
    //   type: [Number, String],
    //   default: 800,
    // },
    // // 签字栏高度
    // height: {
    //   type: [Number, String],
    //   default: 300,
    // },
    // 签字栏字体粗细
    lineWidth: {
      type: [Number, String],
      default: 1,
    },
    // 签字栏字体颜色
    lineColor: {
      type: String,
      default: "#000000",
    },
    // 签字栏 背景颜色
    bgColor: {
      type: String,
      default: "#eee",
    },
    // 是否裁剪
    isCrop: {
      type: Boolean,
      default: false,
    },
    // 是否只读，默认为 true
    readonly: {
      type: Boolean,
      default: false,
    },
    // 是否必填,默认为 false // 是否必填
    required: {
      type: Boolean,
      default: false,
    },
    styleObj: {
      type: Object,
      default: function() {
        return {
          width: 300,
          height: 250,
          opacity: 0.4, //不透明度
          filter: "",
        };
      },
    },
    createObj: {
      type: 1, //分类，0：界面控件，1：表单控件
      id: "stampField_XXXX", //标识，通过组件标识+序号构成
      x: 0, //水平坐标
      y: 0, //垂直坐标
      width: 300, //宽度
      height: 250, //高度s
    },
    // 组件id
  },
  data() {
    return {
      hasDrew: false,
      // resultImg: "",
      points: [
        { x: 35, y: 83 },
        { x: 36, y: 83 },
        { x: 37, y: 83 },
        { x: 39, y: 83 },
        { x: 41, y: 83 },
        { x: 44, y: 83 },
        { x: 47, y: 83 },
        { x: 51, y: 83 },
        { x: 57, y: 83 },
        { x: 61, y: 83 },
        { x: 65, y: 83 },
        { x: 68, y: 83 },
        { x: 70, y: 83 },
        { x: 72, y: 83 },
        { x: 73, y: 83 },
        { x: 73, y: 83 },
        { x: -1, y: -1 },
        { x: 73, y: 83 },
        { x: 75, y: 83 },
        { x: 76, y: 82 },
        { x: 76, y: 81 },
        { x: 78, y: 79 },
        { x: 78, y: 77 },
        { x: 78, y: 75 },
        { x: 79, y: 73 },
        { x: 80, y: 71 },
        { x: 80, y: 69 },
        { x: 81, y: 67 },
        { x: 81, y: 66 },
        { x: 81, y: 64 },
        { x: 82, y: 63 },
        { x: 82, y: 62 },
        { x: 82, y: 61 },
        { x: 82, y: 59 },
        { x: 83, y: 59 },
        { x: 83, y: 58 },
        { x: 84, y: 56 },
        { x: 84, y: 55 },
        { x: 84, y: 54 },
        { x: 84, y: 53 },
        { x: 85, y: 52 },
        { x: 85, y: 51 },
        { x: 85, y: 50 },
        { x: 85, y: 49 },
        { x: 85, y: 48 },
        { x: 86, y: 48 },
        { x: 86, y: 47 },
        { x: 87, y: 45 },
        { x: 87, y: 44 },
        { x: 87, y: 43 },
        { x: 87, y: 42 },
        { x: 87, y: 41 },
        { x: 87, y: 40 },
        { x: 88, y: 40 },
        { x: 88, y: 39 },
        { x: 88, y: 38 },
        { x: 88, y: 37 },
        { x: 88, y: 37 },
        { x: -1, y: -1 },
        { x: 90, y: 34 },
        { x: 90, y: 35 },
        { x: 90, y: 36 },
        { x: 91, y: 36 },
        { x: 91, y: 37 },
        { x: 91, y: 39 },
        { x: 92, y: 39 },
        { x: 93, y: 42 },
        { x: 93, y: 43 },
        { x: 95, y: 46 },
        { x: 95, y: 47 },
        { x: 96, y: 50 },
        { x: 96, y: 52 },
        { x: 98, y: 54 },
        { x: 98, y: 57 },
        { x: 99, y: 59 },
        { x: 100, y: 61 },
        { x: 101, y: 62 },
        { x: 102, y: 65 },
        { x: 103, y: 66 },
        { x: 104, y: 67 },
        { x: 105, y: 69 },
        { x: 105, y: 70 },
        { x: 106, y: 71 },
        { x: 107, y: 72 },
        { x: 107, y: 73 },
        { x: 108, y: 74 },
        { x: 108, y: 75 },
        { x: 109, y: 76 },
        { x: 109, y: 77 },
        { x: 110, y: 77 },
        { x: 110, y: 78 },
        { x: 110, y: 79 },
        { x: 111, y: 80 },
        { x: 111, y: 81 },
        { x: 112, y: 82 },
        { x: 112, y: 82 },
        { x: -1, y: -1 },
        { x: 112, y: 82 },
        { x: 114, y: 82 },
        { x: 116, y: 82 },
        { x: 118, y: 81 },
        { x: 121, y: 81 },
        { x: 124, y: 81 },
        { x: 127, y: 81 },
        { x: 131, y: 81 },
        { x: 135, y: 80 },
        { x: 138, y: 80 },
        { x: 142, y: 80 },
        { x: 145, y: 80 },
        { x: 147, y: 80 },
        { x: 150, y: 80 },
        { x: 152, y: 80 },
        { x: 155, y: 80 },
        { x: 157, y: 80 },
        { x: 160, y: 80 },
        { x: 163, y: 80 },
        { x: 165, y: 80 },
        { x: 166, y: 80 },
        { x: 167, y: 80 },
        { x: 169, y: 80 },
        { x: 170, y: 80 },
        { x: 170, y: 80 },
        { x: -1, y: -1 },
        { x: 35, y: 85 },
        { x: 37, y: 85 },
        { x: 38, y: 86 },
        { x: 41, y: 89 },
        { x: 43, y: 92 },
        { x: 46, y: 94 },
        { x: 48, y: 97 },
        { x: 49, y: 98 },
        { x: 51, y: 100 },
        { x: 53, y: 101 },
        { x: 54, y: 102 },
        { x: 54, y: 103 },
        { x: 55, y: 103 },
        { x: 56, y: 104 },
        { x: 57, y: 105 },
        { x: 59, y: 107 },
        { x: 59, y: 108 },
        { x: 59, y: 109 },
        { x: 60, y: 109 },
        { x: 60, y: 110 },
        { x: 60, y: 111 },
        { x: 61, y: 112 },
        { x: 61, y: 113 },
        { x: 62, y: 114 },
        { x: 63, y: 114 },
        { x: 63, y: 115 },
        { x: 64, y: 115 },
        { x: 64, y: 116 },
        { x: 64, y: 117 },
        { x: 65, y: 118 },
        { x: 66, y: 118 },
        { x: 66, y: 119 },
        { x: 67, y: 120 },
        { x: 67, y: 120 },
        { x: -1, y: -1 },
        { x: 176, y: 79 },
        { x: 175, y: 79 },
        { x: 174, y: 79 },
        { x: 173, y: 80 },
        { x: 173, y: 81 },
        { x: 172, y: 83 },
        { x: 171, y: 84 },
        { x: 169, y: 86 },
        { x: 168, y: 87 },
        { x: 167, y: 87 },
        { x: 166, y: 88 },
        { x: 164, y: 89 },
        { x: 162, y: 90 },
        { x: 162, y: 91 },
        { x: 160, y: 92 },
        { x: 159, y: 93 },
        { x: 157, y: 94 },
        { x: 156, y: 95 },
        { x: 155, y: 95 },
        { x: 154, y: 96 },
        { x: 153, y: 97 },
        { x: 152, y: 98 },
        { x: 151, y: 99 },
        { x: 149, y: 100 },
        { x: 148, y: 100 },
        { x: 147, y: 101 },
        { x: 144, y: 102 },
        { x: 143, y: 102 },
        { x: 142, y: 103 },
        { x: 141, y: 104 },
        { x: 139, y: 105 },
        { x: 137, y: 106 },
        { x: 134, y: 107 },
        { x: 129, y: 108 },
        { x: 125, y: 109 },
        { x: 121, y: 109 },
        { x: 118, y: 110 },
        { x: 115, y: 111 },
        { x: 113, y: 111 },
        { x: 112, y: 111 },
        { x: 111, y: 111 },
        { x: 110, y: 112 },
        { x: 109, y: 112 },
        { x: 109, y: 112 },
        { x: -1, y: -1 },
        { x: 67, y: 121 },
        { x: 66, y: 121 },
        { x: 65, y: 124 },
        { x: 63, y: 125 },
        { x: 63, y: 126 },
        { x: 61, y: 129 },
        { x: 60, y: 131 },
        { x: 58, y: 132 },
        { x: 57, y: 135 },
        { x: 55, y: 137 },
        { x: 54, y: 138 },
        { x: 52, y: 140 },
        { x: 51, y: 141 },
        { x: 49, y: 143 },
        { x: 45, y: 147 },
        { x: 43, y: 149 },
        { x: 39, y: 152 },
        { x: 37, y: 154 },
        { x: 36, y: 155 },
        { x: 34, y: 156 },
        { x: 34, y: 157 },
        { x: 33, y: 158 },
        { x: 32, y: 159 },
        { x: 32, y: 160 },
        { x: 31, y: 162 },
        { x: 30, y: 163 },
        { x: 30, y: 164 },
        { x: 30, y: 166 },
        { x: 29, y: 167 },
        { x: 28, y: 169 },
        { x: 28, y: 170 },
        { x: 28, y: 171 },
        { x: 27, y: 172 },
        { x: 27, y: 172 },
        { x: -1, y: -1 },
        { x: 29, y: 171 },
        { x: 30, y: 170 },
        { x: 31, y: 170 },
        { x: 32, y: 170 },
        { x: 35, y: 169 },
        { x: 38, y: 168 },
        { x: 41, y: 167 },
        { x: 45, y: 166 },
        { x: 49, y: 165 },
        { x: 54, y: 163 },
        { x: 58, y: 160 },
        { x: 61, y: 159 },
        { x: 64, y: 156 },
        { x: 67, y: 154 },
        { x: 69, y: 152 },
        { x: 71, y: 150 },
        { x: 72, y: 149 },
        { x: 74, y: 148 },
        { x: 74, y: 147 },
        { x: 75, y: 147 },
        { x: 75, y: 146 },
        { x: 77, y: 144 },
        { x: 78, y: 143 },
        { x: 78, y: 142 },
        { x: 79, y: 142 },
        { x: 80, y: 141 },
        { x: 81, y: 141 },
        { x: 81, y: 141 },
        { x: -1, y: -1 },
        { x: 86, y: 136 },
        { x: 87, y: 136 },
        { x: 89, y: 137 },
        { x: 89, y: 138 },
        { x: 91, y: 139 },
        { x: 92, y: 142 },
        { x: 94, y: 144 },
        { x: 95, y: 146 },
        { x: 96, y: 148 },
        { x: 97, y: 149 },
        { x: 98, y: 150 },
        { x: 100, y: 153 },
        { x: 101, y: 154 },
        { x: 101, y: 155 },
        { x: 103, y: 156 },
        { x: 104, y: 158 },
        { x: 106, y: 159 },
        { x: 108, y: 160 },
        { x: 110, y: 161 },
        { x: 111, y: 162 },
        { x: 113, y: 163 },
        { x: 115, y: 164 },
        { x: 116, y: 164 },
        { x: 116, y: 164 },
        { x: -1, y: -1 },
        { x: 108, y: 114 },
        { x: 108, y: 117 },
        { x: 109, y: 120 },
        { x: 109, y: 123 },
        { x: 110, y: 129 },
        { x: 111, y: 133 },
        { x: 111, y: 137 },
        { x: 111, y: 141 },
        { x: 111, y: 143 },
        { x: 112, y: 147 },
        { x: 112, y: 149 },
        { x: 112, y: 151 },
        { x: 112, y: 152 },
        { x: 112, y: 154 },
        { x: 112, y: 156 },
        { x: 112, y: 157 },
        { x: 113, y: 158 },
        { x: 113, y: 159 },
        { x: 113, y: 160 },
        { x: 113, y: 161 },
        { x: 113, y: 162 },
        { x: 113, y: 163 },
        { x: 113, y: 163 },
        { x: -1, y: -1 },
      ],
      canvasTxt: null,
      startX: 0,
      startY: 0,
      isDrawing: false,
      sratio: 1,
      // 组件属性
      typeID: "signatureField",
      typeName: "签字域",
      descStr: "手写签字",
      verNum: 1,
      // 数据属性
      dataField: "",
      // 输出的签字图片
      gqValue: "",
      qgValueList: [],
      // 控件类型  0：界面控件，1：表单控件
      subjectType: 1,
      // 控件标识
      id: 1,
    };
  },
  computed: {
    ratio() {
      return this.height / this.width;
    },
    stageInfo() {
      return this.$refs.canvas.getBoundingClientRect();
    },
    myBg() {
      console.log(this.bgColor);
      return this.bgColor ? this.bgColor : "rgba(255, 255, 255, 0)";
    },
    myWidth() {
      console.log(this.width);
      return this.styleObj.width;
    },
    myHeight() {
      console.log(this.height);
      return this.styleObj.height;
    },
  },
  watch: {
    myBg: function(newVal) {
      this.$refs.canvas.style.background = newVal;
    },
    myWidth: function(newVal) {
      this.initCanvas();
      // this.$refs.canvas.style.width = Number(newVal) + "px";
    },
    myHeight: function(newVal) {
      this.initCanvas();
      // this.$refs.canvas.style.height = Number(newVal) + "px";
    },
    points: function(newVal) {
      // const canvas = this.$refs.readcanvas;
      // canvas.height = this.height;
      // canvas.width = this.width;
      // canvas.style.background = this.myBg;
      // console.log(JSON.stringify(newVal));
      // return this.$refs.readcanvas.getBoundingClientRect();
    },
  },
  beforeMount() {
    window.addEventListener("resize", this.$_resizeHandler);
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.$_resizeHandler);
  },
  mounted() {
    // 如果是只读状态则不能签字

    const canvas = this.$refs.canvas;
    canvas.height = this.styleObj.height;
    canvas.width = this.styleObj.width;
    canvas.style.background = this.myBg;
    // canvas.style.opcity = 0.4;

    this.$_resizeHandler();
    this.initCanvas2();
    // 在画板以外松开鼠标后冻结画笔
    document.onmouseup = () => {
      this.isDrawing = false;
    };
  },
  methods: {
    initCanvas2() {
      // console.log("初始化canvas");

      const canvas = this.$refs.readcanvas;
      canvas.height = this.styleObj.height;
      canvas.width = this.styleObj.width;
      canvas.style.background = this.myBg;

      // canvas.style.opacity = this.styleObj.opacity;
      canvas.style.width = this.styleObj.width + "px";
      const realw = parseFloat(window.getComputedStyle(canvas).width);
      canvas.style.height = this.styleObj.height + "px";

      var canvasTxt = canvas.getContext("2d");
      canvasTxt.scale(1 * this.sratio, 1 * this.sratio);
      var sratio = realw / this.width;
      canvasTxt.scale(1 / this.sratio, 1 / this.sratio);
      let ctx = canvas.getContext("2d");
      ctx.beginPath();
      ctx.lineWidth = this.lineWidth;
      ctx.strokeStyle = this.lineColor;
      let newPoints = [];
      this.points.forEach((v, i) => {
        if (v.x == -1 && v.y == -1) {
          let index = i;
          newPoints.push(this.points.splice());
        }
      });
      console.log(newPoints);
      ctx.linCap = "round";
      ctx.lineJoin = "round";

      // ctx.closePath();
      ctx.stroke();
      ctx.closePath();
    },
    drawSmile() {},
    // 初始话canvas
    initCanvas() {
      const canvas = this.$refs.canvas;
      canvas.height = this.styleObj.height;
      canvas.width = this.styleObj.width;
      canvas.style.background = this.myBg;
      // canvas.style.opacity = this.styleObj.opacity;
      this.$_resizeHandler();
    },
    $_resizeHandler() {
      const canvas = this.$refs.canvas;
      // canvas.style.opacity = this.styleObj.opacity;
      canvas.style.width = this.styleObj.width + "px";
      const realw = parseFloat(window.getComputedStyle(canvas).width);
      canvas.style.height = this.styleObj.height + "px";

      this.canvasTxt = canvas.getContext("2d");
      this.canvasTxt.scale(1 * this.sratio, 1 * this.sratio);
      this.sratio = realw / this.width;
      this.canvasTxt.scale(1 / this.sratio, 1 / this.sratio);
    },
    // pc
    mouseDown(e) {
      e = e || event;
      e.preventDefault();

      if (!this.readonly) {
        this.isDrawing = true;
        this.hasDrew = true;

        let obj = {
          x: e.offsetX,
          y: e.offsetY,
        };
        console.log(obj);
        this.qgValueList.push(obj);
        this.drawStart(obj);
      }
    },
    mouseMove(e) {
      e = e || event;
      e.preventDefault();
      if (this.isDrawing) {
        let obj = {
          x: e.offsetX,
          y: e.offsetY,
        };
        console.log(obj);
        // this.qgValueList.push(obj);
        this.drawMove(obj);
      }
    },
    mouseUp(e) {
      e = e || event;
      e.preventDefault();
      let obj = {
        x: e.offsetX,
        y: e.offsetY,
      };
      console.log(obj);
      // this.qgValueList.push(obj);
      if (!this.readonly) {
        this.drawEnd(obj);
      }

      this.isDrawing = false;
    },
    // mobile
    touchStart(e) {
      e = e || event;
      e.preventDefault();
      this.hasDrew = true;
      if (e.touches.length === 1) {
        let obj = {
          x:
            e.targetTouches[0].clientX -
            this.$refs.canvas.getBoundingClientRect().left,
          y:
            e.targetTouches[0].clientY -
            this.$refs.canvas.getBoundingClientRect().top,
        };
        this.drawStart(obj);
      }
    },
    touchMove(e) {
      e = e || event;
      e.preventDefault();
      if (e.touches.length === 1) {
        let obj = {
          x:
            e.targetTouches[0].clientX -
            this.$refs.canvas.getBoundingClientRect().left,
          y:
            e.targetTouches[0].clientY -
            this.$refs.canvas.getBoundingClientRect().top,
        };
        this.drawMove(obj);
      }
    },
    touchEnd(e) {
      e = e || event;
      e.preventDefault();
      if (e.touches.length === 1) {
        let obj = {
          x:
            e.targetTouches[0].clientX -
            this.$refs.canvas.getBoundingClientRect().left,
          y:
            e.targetTouches[0].clientY -
            this.$refs.canvas.getBoundingClientRect().top,
        };
        this.drawEnd(obj);
      }
    },
    // 绘制
    drawStart(obj) {
      console.log(obj, "绘制");
      this.startX = obj.x;
      this.startY = obj.y;
      this.canvasTxt.beginPath();
      this.canvasTxt.moveTo(this.startX, this.startY);
      this.canvasTxt.lineTo(obj.x, obj.y);
      this.canvasTxt.lineCap = "round";
      this.canvasTxt.lineJoin = "round";
      // this.canvasTxt.lineWidth = this.lineWidth * this.sratio;
      this.canvasTxt.lineWidth = this.lineWidth;
      this.canvasTxt.stroke();
      this.canvasTxt.closePath();
      this.points.push(obj);
    },
    drawMove(obj) {
      console.log(obj, "移动");
      this.canvasTxt.beginPath();
      this.canvasTxt.moveTo(this.startX, this.startY);
      this.canvasTxt.lineTo(obj.x, obj.y);
      this.canvasTxt.strokeStyle = this.lineColor;
      // this.canvasTxt.lineWidth = this.lineWidth * this.sratio;
      this.canvasTxt.lineWidth = this.lineWidth;

      this.canvasTxt.lineCap = "round";
      this.canvasTxt.lineJoin = "round";
      this.canvasTxt.stroke();
      this.canvasTxt.closePath();
      this.startY = obj.y;
      this.startX = obj.x;
      this.points.push(obj);
    },
    drawEnd(obj) {
      console.log(obj, "松开");
      this.canvasTxt.beginPath();
      this.canvasTxt.moveTo(this.startX, this.startY);
      this.canvasTxt.lineTo(obj.x, obj.y);
      this.canvasTxt.lineCap = "round";
      this.canvasTxt.lineJoin = "round";
      this.canvasTxt.stroke();
      this.canvasTxt.closePath();
      this.points.push(obj);
      this.points.push({ x: -1, y: -1 });
    },
    // 操作
    generate() {
      const pm = new Promise((resolve, reject) => {
        if (this.required) {
          if (!this.hasDrew) {
            reject(`Warning: Not Signned!`);
            return;
          }
        }

        var resImgData = this.canvasTxt.getImageData(
          0,
          0,
          this.$refs.canvas.width,
          this.$refs.canvas.height
        );
        this.canvasTxt.globalCompositeOperation = "destination-over";
        this.canvasTxt.fillStyle = this.myBg;
        this.canvasTxt.fillRect(
          0,
          0,
          this.$refs.canvas.width,
          this.$refs.canvas.height
        );
        this.gqValue = this.$refs.canvas.toDataURL();
        var gqValue = this.gqValue;
        this.canvasTxt.clearRect(
          0,
          0,
          this.$refs.canvas.width,
          this.$refs.canvas.height
        );
        this.canvasTxt.putImageData(resImgData, 0, 0);
        this.canvasTxt.globalCompositeOperation = "source-over";
        if (this.isCrop) {
          const crop_area = this.getCropArea(resImgData.data);
          var crop_canvas = document.createElement("canvas");
          const crop_ctx = crop_canvas.getContext("2d");
          crop_canvas.width = crop_area[2] - crop_area[0];
          crop_canvas.height = crop_area[3] - crop_area[1];
          const crop_imgData = this.canvasTxt.getImageData(...crop_area);
          crop_ctx.globalCompositeOperation = "destination-over";
          crop_ctx.putImageData(crop_imgData, 0, 0);
          crop_ctx.fillStyle = this.myBg;
          crop_ctx.fillRect(0, 0, crop_canvas.width, crop_canvas.height);
          gqValue = crop_canvas.toDataURL();
          crop_canvas = null;
        }
        resolve(gqValue);
      });
      return pm;
    },
    reset() {
      this.canvasTxt.clearRect(
        0,
        0,
        this.$refs.canvas.width,
        this.$refs.canvas.height
      );
      this.$emit("update:bgColor", "");
      this.$refs.canvas.style.background = "rgba(255, 255, 255, 0)";
      this.points = [];
      this.hasDrew = false;
      this.resultImg = "";
    },
    getCropArea(imgData) {
      var topX = this.$refs.canvas.width;
      var btmX = 0;
      var topY = this.$refs.canvas.height;
      var btnY = 0;
      for (var i = 0; i < this.$refs.canvas.width; i++) {
        for (var j = 0; j < this.$refs.canvas.height; j++) {
          var pos = (i + this.$refs.canvas.width * j) * 4;
          if (
            imgData[pos] > 0 ||
            imgData[pos + 1] > 0 ||
            imgData[pos + 2] ||
            imgData[pos + 3] > 0
          ) {
            btnY = Math.max(j, btnY);
            btmX = Math.max(i, btmX);
            topY = Math.min(j, topY);
            topX = Math.min(i, topX);
          }
        }
      }
      topX++;
      btmX++;
      topY++;
      btnY++;
      const data = [topX, topY, btmX, btnY];
      return data;
    },
  },
};
</script>

<style scoped>
canvas {
  max-width: 100%;
  display: block;
}
</style>
